home *** CD-ROM | disk | FTP | other *** search
- #import "WWSimpleImageView.h"
- #import "aspectRatios.h"
-
- @implementation WWSimpleImageView
-
-
- #define WW_BOTTOMALIGNED 0
- #define WW_TOPALIGNED 1
-
-
- + initialize { return [WWSimpleImageView setVersion:6], self; }
-
- - initFrame:(const NXRect *)r
- {
- [super initFrame:r];
- backgroundColor = NXConvertRGBToColor(0.96, 1.0, 0.6);
- borderType = 0;
- alpha = 1.0;
- image = nil;
- aspectRatioType = WW_ASPECT_DONT_CARE;
- aspectRatio = 1.0;
- scaleToFit = NO;
- imageUnder = NO;
- horizontalLayoutType = NX_LEFTALIGNED;
- verticalLayoutType = WW_BOTTOMALIGNED;
-
- return self;
- }
-
- - awake
- {
- [super awake];
- return self;
- }
-
-
- - free
- {
- if (controlPanel)
- { [controlPanel setFreeWhenClosed:NO];
- [controlPanel close];
- [controlPanel free];
- controlPanel = nil;
- }
- return [super free];
- }
- #define EPSILON 10
-
- - sizeTo:(NXCoord)width :(NXCoord)height
- {
- // don't want to make it too small...
- if (width < EPSILON) return nil;
- if (height < EPSILON) return nil;
-
-
- // let's say it comes in at 100, 100 and you're supposed to be constrained to 4:3
- // you don't want it to get bigger than 100, 100, so... you frob the width, not the height
- switch (aspectRatioType)
- { case WW_ASPECT_DONT_CARE:
- aspectRatio = width/height;
- break;
- case WW_ASPECT_NTSC: // 1.33:1
- height = width/1.33;
- aspectRatio = 1.33;
- break;
- case WW_ASPECT_AMERICAN_WIDESCREEN: // 1.85:1
- //width = height * 1.85;
- height = width/1.85;
- aspectRatio = 1.85;
- break;
- case WW_ASPECT_EUROPEAN_WIDESCREEN: // 1.66:1
- //width = height * 1.66;
- height = width/1.66;
- aspectRatio = 1.66;
- break;
- case WW_ASPECT_VISTA_VISION: // 2.21:1
- //width = height * 1.21;
- height = width/2.21;
- aspectRatio = 2.21;
- break;
- case WW_ASPECT_SQUARE: // 1:1
- if (width < height)
- { height = width;
- }
- else
- { width = height;
- }
- aspectRatio = 1.0;
- break;
- case WW_ASPECT_CUSTOM: //aspectX:aspectY
- if (aspectRatio < 1.0)
- { width = height * aspectRatio;
- }
- else
- { height = width/aspectRatio;
- }
- break;
- default:
- NXLogError("unknown aspect ratio type: %d", aspectRatioType);
- break;
- }
-
- [super sizeTo:width :height];
- [self display];
-
- return self;
- }
-
- - drawSelf:(const NXRect *)theRect :(int)n
- {
- NXPoint p = {0.0, 0.0};
- NXSize imageSize;
-
-
- if (clearTheView)
- { NXSetColor(backgroundColor);
- PSsetalpha(0.0);
- PScompositerect(theRect->origin.x, theRect->origin.y,
- theRect->size.width, theRect->size.height,
- NX_SOVER);
- return self;
- }
-
- [image getSize:&imageSize];
- switch (verticalLayoutType)
- { case WW_BOTTOMALIGNED:
- p.y = 0.0;
- break;
- case WW_TOPALIGNED:
- p.y = theRect->size.height - imageSize.height;
- break;
- default:
- p.y = 0.0;
- break;
- }
- switch (horizontalLayoutType)
- { case NX_LEFTALIGNED:
- p.x = 0.0;
- break;
- case NX_RIGHTALIGNED:
- p.x = theRect->size.width - imageSize.width;
- break;
- case NX_CENTERED:
- if (theRect->size.width > imageSize.width)
- { p.x = (theRect->size.width - imageSize.width)/2.0;
- }
- else
- { p.x = 0.0;
- }
- if (theRect->size.height > imageSize.height)
- { p.y = (theRect->size.height - imageSize.height)/2.0;
- }
- else
- { p.y = 0.0;
- }
- break;
- default:
- p.x = 0.0;
- break;
- }
-
- if (imageUnder)
- { if (scaleToFit)
- { [[image bestRepresentation] drawIn:(const NXRect *)&bounds];
- }
- else
- { [image composite:NX_SOVER toPoint:&p];
- }
- NXSetColor(backgroundColor);
- PSsetalpha(alpha);
- PScompositerect(theRect->origin.x, theRect->origin.y,
- theRect->size.width, theRect->size.height,
- NX_SOVER);
- }
- else
- { NXSetColor(backgroundColor);
- PSsetalpha(alpha);
- PScompositerect(theRect->origin.x, theRect->origin.y,
- theRect->size.width, theRect->size.height,
- NX_SOVER);
- if (scaleToFit)
- { [[image bestRepresentation] drawIn:(const NXRect *)&bounds];
- }
- else
- { [image composite:NX_SOVER toPoint:&p];
- }
- }
-
- if (borderType)
- { NXRect r = *theRect;
-
-
- PSsetalpha(1.0);
-
- r.origin.x++; r.origin.y--;
- NXSetColor(NX_COLORBLACK); NXFrameRect(&r);
-
- r.origin.x--, r.origin.y++;
- NXSetColor(NX_COLORGRAY); NXFrameRect(&r);
-
- r.origin.x--; r.size.width++; r.size.height++;
- NXSetColor(NX_COLORWHITE); NXFrameRect(&r);
- }
-
- return self;
- }
-
- - setBorderType:(int)newBorderType { borderType = newBorderType; return self; }
- - (int)borderType { return borderType; }
-
- //
- - sizeToImage:sender
- {
- NXSize s;
-
-
- if (image)
- { [image getSize:&s];
- [self sizeTo:s.width :s.height];
- }
- return self;
- }
-
- - setScaleToFit:(BOOL)flag { scaleToFit = flag; return self; }
- - (BOOL)scaleToFit { return scaleToFit; }
- - setImageUnder:(BOOL)flag { imageUnder = flag; return self; }
- - (BOOL)imageUnder { return imageUnder; }
-
- - (int)aspectRatioType { return aspectRatioType; }
- - (float)aspectRatio { return aspectRatio; }
- - setAspectRatioFromMatrix:sender
- {
- NXRect newRect;
-
-
- [self getFrame:&newRect];
- aspectRatioType = [[sender selectedCell] tag];
- switch (aspectRatioType)
- { case WW_ASPECT_DONT_CARE:
- break;
- case WW_ASPECT_NTSC: // 1.33:1
- newRect.size.height = newRect.size.width/1.33;
- break;
- case WW_ASPECT_AMERICAN_WIDESCREEN: // 1.85:1
- newRect.size.height = newRect.size.width/1.85;
- break;
- case WW_ASPECT_EUROPEAN_WIDESCREEN: // 1.66:1
- newRect.size.height = newRect.size.width/1.66;
- break;
- case WW_ASPECT_VISTA_VISION: // 2.21:1
- newRect.size.height = newRect.size.width/2.21;
- break;
- case WW_ASPECT_SQUARE: // 1:1
- if (newRect.size.width < newRect.size.height)
- { newRect.size.height = newRect.size.width;
- }
- else
- { newRect.size.width = newRect.size.height;
- }
- break;
- case WW_ASPECT_CUSTOM: //aspectX:aspectY
- if (aspectRatio < 1.0)
- { newRect.size.width = newRect.size.height * aspectRatio;
- }
- else
- { newRect.size.height = newRect.size.width/aspectRatio;
- }
- break;
- default:
- NXLogError("unknown aspect ratio type: %d", aspectRatioType);
- break;
- }
- [self sizeTo:newRect.size.width :newRect.size.height];
-
- return self;
- }
- - setAspectRatioType:(int)newAspectRatioType
- {
- NXRect newRect;
-
-
- [self getFrame:&newRect];
- aspectRatioType = newAspectRatioType;
- switch (aspectRatioType)
- { case WW_ASPECT_DONT_CARE:
- break;
- case WW_ASPECT_NTSC: // 1.33:1
- newRect.size.height = newRect.size.width/1.33;
- break;
- case WW_ASPECT_AMERICAN_WIDESCREEN: // 1.85:1
- newRect.size.height = newRect.size.width/1.85;
- break;
- case WW_ASPECT_EUROPEAN_WIDESCREEN: // 1.66:1
- newRect.size.height = newRect.size.width/1.66;
- break;
- case WW_ASPECT_VISTA_VISION: // 2.21:1
- newRect.size.height = newRect.size.width/2.21;
- break;
- case WW_ASPECT_SQUARE: // 1:1
- if (newRect.size.width < newRect.size.height)
- { newRect.size.height = newRect.size.width;
- }
- else
- { newRect.size.width = newRect.size.height;
- }
- break;
- case WW_ASPECT_CUSTOM: //aspectX:aspectY
- if (aspectRatio < 1.0)
- { newRect.size.width = newRect.size.height * aspectRatio;
- }
- else
- { newRect.size.height = newRect.size.width/aspectRatio;
- }
- break;
- default:
- NXLogError("unknown aspect ratio type: %d", aspectRatioType);
- break;
- }
- [self sizeTo:newRect.size.width :newRect.size.height];
-
- return self;
- }
- //
- - setAspectRatio:sender
- {
- NXRect newRect;
-
-
- [self getFrame:&newRect];
- aspectRatio = [sender floatValue];
-
- if (aspectRatioType != WW_ASPECT_CUSTOM)
- { return self;
- }
- if (aspectRatio < 1.0)
- { newRect.size.width = newRect.size.height * aspectRatio;
- }
- else
- { newRect.size.height = newRect.size.width/aspectRatio;
- }
- [self sizeTo:newRect.size.width :newRect.size.height];
-
- return self;
- }
- //
- - setHorizontalLayoutFromMatrix:sender { horizontalLayoutType = [[sender selectedCell] tag]; return self; }
- - (int)horizontalLayoutType { return horizontalLayoutType; }
-
- - setVerticalLayoutFromMatrix:sender { verticalLayoutType = [[sender selectedCell] tag]; return self; }
- - (int)verticalLayoutType { return verticalLayoutType; }
-
-
- - (NXColor) backgroundColor { return backgroundColor; }
- - setBackgroundColor:(NXColor)c { return backgroundColor = c, self; }
- - (float) alpha { return alpha; }
- - setBackgroundAlpha:(float)n { return alpha = n, self; }
-
- - saveImage:sender
- {
- static id savePanel=nil;
- NXStream *ts;
-
-
- if (!savePanel)
- { savePanel=[SavePanel new];
- }
-
- [savePanel setRequiredFileType:"tiff"];
- if([savePanel runModal])
- { ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
- [image writeTIFF:ts allRepresentations:NO usingCompression:NX_TIFF_COMPRESSION_LZW andFactor:1.0];
- NXSaveToFile(ts, [savePanel filename]);
- NXCloseMemory(ts,NX_FREEBUFFER);
- }
-
- return self;
- }
-
- - setImageFile:(const char *)filename
- {
- // It's actually a bad idea to free this image, because it might be shared...
- if (filename && *filename)
- { image = [NXImage findImageNamed:filename];
- if (!image)
- { image = [[NXImage alloc] init];
- [image setDataRetained:YES];
- if (![image loadFromFile:filename])
- { NXLogError("unable to load image from file <%s>\n", filename);
- return nil;
- }
- }
- }
- clearTheView = YES;
- [self display];
- clearTheView = NO;
- [window display];
- return self;
- }
-
- - setImage:i
- { image = i;
- clearTheView = YES;
- [self display];
- clearTheView = NO;
- [window display];
- return self;
- }
- - image { return image; }
-
- - (const char *)getInspectorClassName { return "WWSimpleImageViewIBInspector"; }
-
- - revertControlPanel:sender
- {
- [theColor setColor:[self backgroundColor]];
- [alphaSlider setFloatValue:[self alpha]];
- [horizontalLayoutMatrix selectCellWithTag:[self horizontalLayoutType]];
- [verticalLayoutMatrix selectCellWithTag:[self verticalLayoutType]];
- [borderTypeMatrix selectCellWithTag:[self borderType]];
- clearTheView = YES; [self display];
- clearTheView = NO; [window display]; NXPing();
-
- return self;
- }
-
- - loadControlPanel
- {
- char buf[MAXPATHLEN + 1];
- id bundle;
-
-
- // we want to support two different things here.
- // 1st scenario: lots of MovieViews, screen space is expensive, we want to have these control panels
-
- if (!controlPanel)
- { bundle = [NXBundle bundleForClass:[self class]];
- [bundle getPath:buf forResource:"WWSimpleImageViewControlPanel" ofType:"nib"];
- [NXApp loadNibFile:buf owner:self withNames:NO fromZone:[self zone]];
- if (!controlPanel)
- { NXLogError("problem loading WWSimpleMovieViewControlPanel\n");
- return nil;
- }
- [controlPanel setDelegate:self];
- }
- [self revertControlPanel:nil];
- [controlPanel makeKeyAndOrderFront:self];
- return self;
- }
-
-
- - mouseDown:(NXEvent *)theEvent
- {
- if (theEvent->flags & NX_COMMANDMASK) // show the control panel
- { [self loadControlPanel];
- return self;
- }
- return self;
- }
-
-
- #define typeVectorVersion1 "@f"
- #define typeValuesVersion1 &image, &alpha
-
- #define typeVectorVersion2 "@fif"
- #define typeValuesVersion2 &image, &alpha, &aspectRatioType, &aspectRatio
-
- #define typeVectorVersion3 "@fifcc"
- #define typeValuesVersion3 &image, &alpha, &aspectRatioType, &aspectRatio, &imageUnder, &scaleToFit
-
- #define typeVectorVersion4 "@fifcci"
- #define typeValuesVersion4 &image, &alpha, &aspectRatioType, &aspectRatio, &imageUnder, &scaleToFit, &borderType
-
- #define typeVectorVersion5 "@fifccii"
- #define typeValuesVersion5 &image, &alpha, &aspectRatioType, &aspectRatio, &imageUnder, &scaleToFit, &borderType, &horizontalLayoutType
-
- #define typeVector "@fifcciii"
- #define typeValues &image, &alpha, &aspectRatioType, &aspectRatio, &imageUnder, &scaleToFit, &borderType, &horizontalLayoutType, &verticalLayoutType
-
- - read:(NXTypedStream*)stream
- {
- int version;
- [super read:stream];
-
-
- version = NXTypedStreamClassVersion(stream, "WWSimpleImageView");
- if (version == 0) NXReadTypes(stream, "i", &version), version=1;
- if (version == 1)
- { NXReadTypes(stream, typeVectorVersion1, typeValuesVersion1);
- backgroundColor = NXReadColor(stream);
- aspectRatioType = WW_ASPECT_SQUARE;
- aspectRatio = 1.0;
- imageUnder = NO;
- scaleToFit = NO;
- borderType = 0;
- horizontalLayoutType = NX_LEFTALIGNED;
- verticalLayoutType = WW_BOTTOMALIGNED;
- }
- if (version == 2)
- { NXReadTypes(stream, typeVectorVersion2, typeValuesVersion2);
- backgroundColor = NXReadColor(stream);
- imageUnder = NO;
- scaleToFit = NO;
- borderType = 0;
- horizontalLayoutType = NX_LEFTALIGNED;
- verticalLayoutType = WW_BOTTOMALIGNED;
- }
- if (version == 3)
- { NXReadTypes(stream, typeVectorVersion3, typeValuesVersion3);
- backgroundColor = NXReadColor(stream);
- borderType = 0;
- horizontalLayoutType = NX_LEFTALIGNED;
- verticalLayoutType = WW_BOTTOMALIGNED;
- }
- if (version == 4)
- { NXReadTypes(stream, typeVectorVersion4, typeValuesVersion4);
- backgroundColor = NXReadColor(stream);
- horizontalLayoutType = NX_LEFTALIGNED;
- verticalLayoutType = WW_BOTTOMALIGNED;
- }
- if (version == 5)
- { NXReadTypes(stream, typeVectorVersion5, typeValuesVersion5);
- backgroundColor = NXReadColor(stream);
- verticalLayoutType = WW_BOTTOMALIGNED;
- }
- if (version == 6)
- { NXReadTypes(stream, typeVector, typeValues);
- backgroundColor = NXReadColor(stream);
- }
- return self;
- }
-
-
- - write:(NXTypedStream *)stream
- {
- [super write:stream];
- NXWriteTypes(stream, typeVector, typeValues);
- NXWriteColor(stream, backgroundColor);
-
- return self;
- }
-
-
-
- @end
-